// Copyright 2019 orivil.com. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found at https://mit-license.org.

package container

import (
	"bytes"
	"encoding/json"
	"gitee.com/tugoer/psys/models"
	"gitee.com/tugoer/psys/utils"
	"io/ioutil"
	"os"
	"sync"
)

var gameDataDir = "data/game"

func init() {
	err := os.MkdirAll(gameDataDir, os.ModePerm)
	if err != nil {
		panic(err)
	}
}

func readGameData(id string) (data []byte, err error) {
	return ioutil.ReadFile(gameFile(id))
}

func writeGameData(id string, data []byte) error {
	return ioutil.WriteFile(gameFile(id), data, os.ModePerm)
}

func removeGameData(id string) (err error) {
	return os.Remove(gameFile(id))
}

func gameFile(id string) string {
	return gameDataDir + "/" + id + ".json"
}

var Game = &game{data: make(map[string]*models.GameData, 10)}

type game struct {
	data map[string]*models.GameData
	mu   sync.RWMutex
}

func (ec *game) Flash(id string) error {
	ec.mu.Lock()
	defer ec.mu.Unlock()
	delete(ec.data, id)
	return removeGameData(id)
}

func (ec *game) Get(id string) (*models.GameData, error) {
	ec.mu.Lock()
	defer ec.mu.Unlock()
	g := ec.data[id]
	if g == nil {
		// 本地获取数据
		data, err := readGameData(id)
		if err != nil {
			if os.IsNotExist(err) {
				// 拉取远程数据
				gd, err := utils.GetGameData(id)
				if err != nil {
					return nil, err
				} else {
					g = &models.GameData{}
					err = models.UnmarshalGameData(g, bytes.TrimSpace(gd.Data))
					if err != nil {
						panic(err)
						return nil, err
					}
					g.HeadImgConfig = string(gd.HeadImgCfg)
					g.NameConfig = string(gd.NameCfg)
					g.SpecialResultData = string(gd.SpecialData)
					// 保存远程数据
					data, err = json.Marshal(g)
					if err != nil {
						panic(err)
						return nil, err
					}
					err = writeGameData(id, data)
					if err != nil {
						return nil, err
					}
				}
			} else {
				return nil, err
			}
		} else {
			// 解析本地数据
			g = &models.GameData{}
			err = json.Unmarshal(data, g)
			if err != nil {
				return nil, err
			}
		}
		ec.data[id] = g
	}
	return g, nil
}

//func InitGameDataImages(gd *models.GameData) error {
//	gd.Logo = ImageName(gd.Logo)
//	err := SaveImageIfNotExist(gd.Logo)
//	if err != nil {
//		return err
//	}
//	for _, q := range gd.Question {
//		q.Img
//	}
//}
//
//func ImageName(img string) string {
//	idx := strings.IndexAny(img, "?#")
//	if idx > 0 {
//		return img[:idx]
//	} else {
//		return img
//	}
//}
//
//func SaveImageIfNotExist(name string) error {
//	ok, err := image.Storage.IsExist(name)
//	if err != nil {
//		return err
//	}
//	if !ok {
//		URL := env.Env.ImageUrl(name)
//		resp, err := http.Get(URL)
//		if err != nil {
//			return err
//		}
//		defer resp.Body.Close()
//		data, err := ioutil.ReadAll(resp.Body)
//		if err != nil {
//			return err
//		}
//		return image.Storage.Write(name, data)
//	} else {
//		return nil
//	}
//}
